package com.roin.learn.activiti.controller;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.roin.learn.activiti.base.BaseController;
import com.roin.learn.activiti.base.SysConstent;
import com.roin.learn.activiti.command.ProcessInstanceDiagramCmd;
import com.roin.learn.activiti.command.UpdateProcessCmd;
import com.github.pagehelper.util.StringUtil;
import com.roin.learn.activiti.entity.ResourceResult;
import com.roin.learn.activiti.entity.User;
import com.roin.learn.activiti.exception.BusinessException;
import com.roin.learn.activiti.service.ProcessService;
import com.roin.learn.activiti.service.UserService;
import com.roin.learn.activiti.utils.IoUtils;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.impl.cmd.GetDeploymentProcessDiagramCmd;
import org.activiti.engine.impl.cmd.SetProcessInstanceNameCmd;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

/**
 * 流程管理控制器
 */
@Controller
@RequestMapping("process")
public class ProcessController extends BaseController {

    @Resource
    ProcessService processService;
    @Resource
    ManagementService managementService;
    @Resource
    TaskService taskService;
    @Resource
    RepositoryService repositoryService;
    @Resource
    RuntimeService runtimeService;
    @Resource
    HistoryService historyService;
    @Resource
    IdentityService identityService;
    @Resource
    FormService formService;
    @Resource
    UserService userService;
    @Resource
    ProcessEngineConfiguration processEngineConfiguration;

    /*-----------------------流程模型-------------------------------start*/

    /*-----------------------流程模型-------------------------------end*/

    /*-----------------------流程定义-------------------------------start*/

    /*-----------------------流程定义-------------------------------end*/

    /*-----------------------流程实例-------------------------------start*/

    /*-----------------------流程实例-------------------------------end*/


    /*-----------------------流程任务-------------------------------start*/
    /**
     * 转到任务列表页面
     * @return
     */
    @RequestMapping("task.htm")
    public ModelAndView toTask(@RequestParam(required = false) String processDefinitionKey){
        ModelAndView mav = new ModelAndView("process/task");
        try {
            List<Task> taskList = processService.queryTaskList(processDefinitionKey);
            mav.addObject("taskList",taskList);
        } catch (Exception e) {
            mav.addObject(ERROR,SysConstent.MSG_SYS_ERROR);
            log.error("查询任务异常",e);
        }
        return mav;
    }
    /**
     * 完成任务
     * @param id 任务ID
     * @return
     */

    @RequestMapping("task/complete.do")
    @ResponseBody
    public ResourceResult completeTask(@RequestParam(required = true) String id){
        ResourceResult result = new ResourceResult();
        try {
            processService.completeTask(id,null);
            result.setMessage("提交成功！").setSuccess(true);
        } catch (Exception e) {
            log.error("完成任务异常",e);
            result.setMessage(SysConstent.MSG_SYS_ERROR);
        }
        return result;
    }
    /**
     * 通过任务表单完成任务
     * @param id 任务ID
     * @param properties 表单属性值json字符串
     * @return
     */

    @RequestMapping("task/completeByFormData.do")
    @ResponseBody
    public ResourceResult completeTaskByFormData(String id, String properties, HttpSession session){
        ResourceResult result = new ResourceResult();
        try {
            checkLogin(session);
            Map formProperties = JSON.parseObject(properties,Map.class);
            formService.submitTaskFormData(id, formProperties);
            result.setMessage("提交成功！").setSuccess(true);
        } catch (Exception e) {
            log.error("完成任务异常",e);
            result.setMessage(SysConstent.MSG_SYS_ERROR);
        }
        return result;
    }
    /*-----------------------流程任务-------------------------------end*/



    /**
     * 通过流程定义ID或者流程实例ID或者任务ID查看流程图
     * @param processDefinitionId 流程定义ID
     * @param processInstanceId 流程实例ID
     * @param taskId 任务ID
     * @param response
     */
    @RequestMapping("/graph.htm")
    public void showGraphById(String processDefinitionId, String processInstanceId,String taskId, HttpServletResponse response){

        response.setContentType("image/png");
        Command<InputStream> cmd = null;
        if (processDefinitionId != null) {
            cmd = new GetDeploymentProcessDiagramCmd(processDefinitionId);
        }
        if (processInstanceId != null) {
            cmd = new ProcessInstanceDiagramCmd(processInstanceId,processEngineConfiguration);
        }
        if (taskId != null) {
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            cmd = new ProcessInstanceDiagramCmd(task.getProcessInstanceId(),processEngineConfiguration);
        }
        try {
            if (cmd != null) {
                InputStream is = managementService.executeCommand(cmd);
                IOUtils.copy(is,response.getOutputStream());
            }
        }catch (IOException e){
            log.error("显示流程图出错",e);
        }
    }



    @RequestMapping("/getById.do")
    @ResponseBody
    public ResourceResult getById(@RequestParam("id") String id) {
        ResourceResult result = new ResourceResult();
        List<ProcessDefinition> pds = processService.findProcessDefintion(null,id,null,null,null);
        if (pds==null||pds.isEmpty())
            result.setMessage("找不到ID为"+id+"的流程定义！");
        else {
            result.setSuccess(true);
            result.setData(pds);
        }
        return result;
    }
    @RequestMapping("/getByDeploymentId.do")
    @ResponseBody
    public ResourceResult getByDeploymentId(@RequestParam("deploymentId") String deploymentId) {
        ResourceResult result = new ResourceResult();
        List<ProcessDefinition> pds = processService.findProcessDefintion(deploymentId,null,null,null,null);
        if (pds==null||pds.isEmpty())
            result.setMessage("找不到deploymentId为"+deploymentId+"的流程定义！");
        else {
            result.setSuccess(true);
            result.setData(pds);
        }
        return result;
    }
}
